import { Bot } from "./Bot.js";
import { Act, ActArg, ActState } from "../type/actType.js";
import { ActArray } from "./act/actArray.js";
import { parseAct, parseActArg } from "../utils/string/parse.js";

export class ActManager {
  _bot: Bot = null as any;
  _actBlackSet: Set<string> = new Set();
  static _actMap: Map<string, Act> = new Map();
  _state: ActState = "空闲";
  _actDoc: string = `# **行动文档(重要)**\n你可以使用以下行动来在游戏中执行操作或者获取额外信息，无论你的人设是什么都可以调用这些行动\n使用语法: &ActName 或者如果行动需要参数 &ActName("参数1", 1.2,...)\n不要使用代码块，字符串使用双引号。每次回复只能调用一个行动，后续的行动和注释将被忽略，不允许自己编造行动调用结果\n`;

  constructor(bot?: Bot, ActBlackList?: Array<string>, extraAct?: Array<Act>) {
    if (bot) this._bot = bot;
    let acts = [...ActArray];
    if (extraAct) acts = acts.concat(extraAct);
    for (const act of acts) ActManager._actMap.set(act.name, act);
    if (ActBlackList) {
      acts = acts.filter((act) => !ActBlackList.includes(act.name));
      for (const actName of ActBlackList) this._actBlackSet.add(actName);
    }
    for (const act of acts) {
      this._actDoc += `## &${act.name}\n描述:${act.description}\n`;
      if (act.params && act.params.length > 0) {
        this._actDoc += `参数:\n`;
        for (const arg of act.params) {
          this._actDoc += `- ${arg.name}(${arg.type})`;
          if (arg.description) this._actDoc += `: ${arg.description}`;
          this._actDoc += `\n`;
        }
      }
    }
  }

  //TODO? 执行行动
  async executeAct(content: string): Promise<{ content: string; toolName: string }> {
    const actCall = parseAct(content);
    if (!actCall) return { content: "", toolName: "" };
    if (this._actBlackSet.has(actCall.actName))
      throw new Error(`行动 ${actCall.actName} 被禁止使用`);
    if (!ActManager._actMap.has(actCall.actName)) throw new Error(`行动 ${actCall.actName} 不存在`);

    const act = ActManager._actMap.get(actCall.actName) as Act;
    if (actCall.actArgs.length < (act.params?.length ?? 0)) {
      throw new Error(
        `行动 ${actCall.actName} 需要 ${act.params?.length ?? 0} 个参数, 但只提供了 ${
          actCall.actArgs.length
        } 个参数`
      );
    }

    // 解析参数
    const parseArgs: Record<string, any> = {};
    for (let i = 0; i < (act.params?.length ?? 0); i++) {
      const param = act.params?.[i] as ActArg;
      const arg = actCall.actArgs[i] as string;
      try {
        parseArgs[param.name] = parseActArg(arg, param.type);
      } catch (e) {
        throw new Error(
          `行动 ${actCall.actName} 的参数 ${param.name} 解析失败: ${(e as Error).message}`
        );
      }
    }

    // 执行行动
    const result = (await act.perform(this._bot, parseArgs)) ?? "";
    return { content: result, toolName: actCall.actName };
  }

  getActDoc(): Readonly<string> {
    return `# 当前行动状态\n${this._state}\n` + this._actDoc;
  }
}
